package com.example.rabbitmq.service;

import com.example.rabbitmq.domain.User;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

/**
 * 消息消费服务类
 * 负责监听RabbitMQ队列，接收并处理发布的消息
 * 实现基于发布/订阅模式的消息消费逻辑
 */
@Service // 标识为服务层组件，由Spring容器管理
public class MessageConsumerService {

    /**
     * 邮件业务消息消费者
     * 使用@RabbitListener注解监听指定队列，自动接收并处理消息
     * 通过@QueueBinding注解动态绑定队列、交换机和路由规则
     * @param user 接收的消息对象（由消息转换器自动反序列化为User类型）
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue("email.queue"), // 绑定的队列名称
            exchange = @Exchange(value = "pub/sub.exchange", type = "fanout") // 绑定的交换机（名称和类型）
    ))
    public void psubConsumerEmail(User user) {
        // 处理邮件业务逻辑，这里简单打印接收到的用户名
        System.out.println("邮件业务接收到消息：" + user.getUsername());
    }

    /**
     * 短信业务消息消费者
     * 与邮件消费者监听同一个交换机，实现发布/订阅模式
     * @param user 接收的消息对象（User类型）
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue("sms.queue"), // 绑定的队列名称
            exchange = @Exchange(value = "pub/sub.exchange", type = "fanout") // 绑定的交换机
    ))
    public void psubConsumerSms(User user) {
        // 处理短信业务逻辑，打印接收到的用户名
        System.out.println("短信业务接收到消息：" + user.getUsername());
    }

    /**
     * 邮件业务消息消费者（字节数组方式，当前注释掉）
     * 直接接收消息字节数组，需要手动进行反序列化
     * @param message 原始消息对象，包含消息体、属性等信息
     */
   /* @RabbitListener(queues = "email.queue") // 直接指定监听的队列名称
    public void psubConsumerEmail(Message message){
        // 获取消息体字节数组
        byte[] body = message.getBody();
        // 转换为字符串（适用于文本消息）
        String s = new String(body);
        System.out.println("邮件业务接收到消息：" + s);
    }*/

    /**
     * 短信业务消息消费者（字节数组方式，当前注释掉）
     * @param message 原始消息对象
     */
   /* @RabbitListener(queues = "sms.queue")
    public void psubConsumerSms(Message message){
        byte[] body = message.getBody();
        String s = new String(body);
        System.out.println("短信业务接收到消息：" + s);
    }*/

    /**
     * 路由模式（Routing）的全级别消息消费者
     * 监听并消费所有级别的消息（info、error、warning）
     *
     * @RabbitListener: 标识该方法为RabbitMQ消息消费者，用于监听指定队列
     * @QueueBinding: 定义队列、交换机及绑定关系的组合配置
     * - value = @Queue("routing.all.queue"): 指定要监听的队列名称为"routing.all.queue"
     * - exchange = @Exchange(value = "routing.exchange", type = "direct"):
     *   绑定到名称为"routing.exchange"的Direct类型交换机（路由模式必须使用Direct交换机）
     * - key = {"routingkey.error", "routingkey.info", "routingkey.warning"}:
     *   绑定键（Binding Key）列表，与交换机类型匹配，只有消息的路由键与这些绑定键之一完全匹配时，
     *   消息才会被路由到该队列
     *
     * @param message 接收到的消息内容（字符串类型，由消息转换器自动处理）
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue("routing.all.queue"),
            exchange = @Exchange(value = "routing.exchange", type = "direct"),
            key = {"routingkey.error", "routingkey.info", "routingkey.warning"}
    ))
    public void routingConsumerAll(String message) {
        // 打印接收到的全级别消息，实际应用中可根据需求进行业务处理
        System.out.println("接收到info、error、warning等级别日志消息:" + message);
    }

    /**
     * 主题模式（Topic）的邮件消息消费者
     * 专门处理与邮件相关的信息类消息，通过通配符匹配特定格式的路由键
     *
     * @RabbitListener: 标识该方法为RabbitMQ消息消费者
     * @QueueBinding: 定义队列、交换机及绑定关系
     * - value = @Queue("topic.email.queue"): 监听的队列名称为"topic.email.queue"
     * - exchange = @Exchange(value = "topic.exchange", type = "topic"): 绑定到Topic类型的"topic.exchange"交换机
     * - key = "info.#.email.#": 绑定键（通配符规则）
     *   - "info": 匹配消息级别为信息类
     *   - "#": 匹配零个或多个单词（用于中间层级的灵活匹配）
     *   - "email": 匹配包含邮件业务的标识
     *   整体规则表示：接收所有以"info"开头、包含"email"且之后可有任意层级的消息
     *   例如匹配"info.user.register.email"、"info.order.email.notice"等路由键
     *
     * @param message 接收到的消息内容（字符串类型）
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue("topic.email.queue"),
            exchange = @Exchange(value = "topic.exchange", type = "topic"),
            key = "info.#.email.#"
    ))
    public void topicConsumerEmail(String message) {
        // 处理邮件相关的信息类消息，打印接收内容
        System.out.println("接收到邮件订阅需求处理消息：" + message);
    }

    /**
     * 主题模式（Topic）的短信消息消费者
     * 专门处理与短信相关的信息类消息，通过通配符匹配特定格式的路由键
     *
     * @RabbitListener: 标识该方法为RabbitMQ消息消费者
     * @QueueBinding: 定义队列、交换机及绑定关系
     * - value = @Queue("topic.sms.queue"): 监听的队列名称为"topic.sms.queue"
     * - exchange = @Exchange(value = "topic.exchange", type = "topic"): 绑定到Topic类型的"topic.exchange"交换机
     * - key = "info.#.sms.#": 绑定键（通配符规则）
     *   - "info": 匹配消息级别为信息类
     *   - "#": 匹配零个或多个单词
     *   - "sms": 匹配包含短信业务的标识
     *   整体规则表示：接收所有以"info"开头、包含"sms"且之后可有任意层级的消息
     *   例如匹配"info.user.login.sms"、"info.order.sms.verify"等路由键
     *
     * @param message 接收到的消息内容（字符串类型）
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue("topic.sms.queue"),
            exchange = @Exchange(value = "topic.exchange", type = "topic"),
            key = "info.#.sms.#"
    ))
    public void topicConsumerSms(String message) {
        // 处理短信相关的信息类消息，打印接收内容
        System.out.println("接收到短信订阅需求处理消息：" + message);
    }


}